home *** CD-ROM | disk | FTP | other *** search
- Path: chronicle.mti.sgi.com!austern
- From: jones@cais.cais.com (Ben Jones)
- Newsgroups: comp.std.c++
- Subject: Re: Q: Generic Callbacks -- "Object->*func(...)"
- Date: 21 Feb 1996 09:50:36 PST
- Organization: Capital Area Internet Service info@cais.com 703-448-4470
- Approved: austern@isolde.mti.sgi.com
- Message-ID: <4gfdck$i0g@zippy.cais.net>
- References: <4fti32$p3p@bcarh8ab.bnr.ca>
- NNTP-Posting-Host: isolde.mti.sgi.com
- X-Original-Date: 21 Feb 1996 15:23:00 GMT
- X-Newsreader: TIN [version 1.2 PL2]
- X-Auth: PGPMoose V1.1 PGP comp.std.c++
- iQBVAwUBMStbmEy4NqrwXLNJAQETwQIAmk+iMfjzJ9J9eWwRTysUcfjhUKnQ0U9j
- JDMFC4YaVYqv0/LNp1jCF46owo3wSwrUySlSt2/eRy6hi5Rrrf56YQ==
- =AlDY
- Originator: austern@isolde.mti.sgi.com
-
- brian (b.c.) white (bcwhite@bnr.ca) wrote:
- : Does the C++ standard allow for a generic callback to be specified?
-
- : Basically, I'd like to be able to pass an arbitrary object and function of
- : that object to be called at some later time. For example:
-
- : void DoIt(ANYOBJECT* Object, void (ANYOBJECT::*CallBack)( ...parmlist... ))
- : {
- : [...]
- : Object->*CallBack( ...parms... );
- : [...]
- : }
-
-
- : I'd like to be able to call "DoIt" with any type of object and a pointer to
- : any of that object's member functions that match the 'parmlist'. As it
- : stands, any object passed in would have to be in the same class hierarchy
- : as ANYOBJECT, thus basically requiring a unified class hierachy in order to
- : do this genericly.
-
- : [snip snip]
-
- : So... Is this possible?
-
-
- The following kluge works on all platforms that I have tried it on
- including Sun, SGI, Alpha, Macintosh, PC:
-
- #include <stdarg.h>
-
- class Callback
- {
- public:
- typedef void (Callback::*MF)();
- typedef void (*F)();
-
- Callback(F ff=0)
- {
- p = 0;
- f = ff;
- }
- Callback(void *pp,...)
- {
- va_list ap; va_start(ap,pp);
- p=(Callback*)pp;
- mf = va_arg(ap,MF);
- }
- virtual void operator()()
- {
- if (p)
- (p->*mf)();
- else if (f)
- f();
- }
-
- private:
- Callback *p;
- union { MF mf; F f; };
- };
-
- Essentially, the "Callback" class consists of an object pointer and a
- function pointer. The constructors provide for two cases: a global
- function (which causes a null object pointer to be stored) or a paired
- object and member function pointer. The parenthesis operator is
- overloaded so that a Callback object may be executed as though it were
- a function pointer. It is declared virtual so that virtual callback
- functions will work properly.
-
- Now we can set up a callback very easily:
-
- Callback mycallback;
- ...
- mycallback = function;
- ...
- mycallback = Callback(&object,&classname::memberfunction);
- ...
- mycallback();
-
- The above class can be defined with a template or macro such that
- you can make variations on it for callback functions with various
- argument types.
-
- It is not typesafe. It is your responsibility to make sure that
- "object" and "memberfunction" are compatible. However, as I said
- before, it works everywhere that I've tried it.
-
- ------------
-
- A simple extension to C++ would allow for a perfectly typesafe
- callback scheme. All that is necessary is that the following
- expressions:
-
- object.function
- pointer->function
-
- be LEGAL without having to be followed by (). For them to be
- legal there needs to be a container which can hold the values
- of those expressions. I would suggest:
-
- type (::*callback)(type1,type2,...)
-
- That is, if you specify "::*" without a qualifying classname,
- then "callback" can accept an expression like "object.function"
- provided that "function" has a prototype of "type(type1,type2,..)".
- Simple as that.
-
- ANSI commitee please take note.
-
- Ben Jones
- Hughes Information Technology
- bjones@eos.hitc.com
- jones@cais.com
- ---
- [ To submit articles: Try just posting with your newsreader. If that fails,
- use mailto:std-c++@ncar.ucar.edu
- FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html
- Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html
- Comments? mailto:std-c++-request@ncar.ucar.edu
- ]
-